package com.mcc.app.carbonEmission.service.impl;

import java.io.File;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mcc.app.carbonEmission.domain.FilenameDTO;
import com.mcc.app.carbonEmission.domain.ReportAssistHan;
import com.mcc.app.carbonEmission.domain.ReportProductData;
import com.mcc.app.carbonEmission.service.IReportAssistHanService;
import com.mcc.common.config.ProjectConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mcc.app.carbonEmission.mapper.ReportAssistMapper;
import com.mcc.app.carbonEmission.domain.ReportAssist;
import com.mcc.app.carbonEmission.service.IReportAssistService;

/**
 * 辅助报表Service业务层处理
 *
 * @author gxy
 * @date 2025-07-03
 */
@Service
@Slf4j
public class ReportAssistServiceImpl implements IReportAssistService {

    @Autowired
    private ReportAssistMapper reportAssistMapper;

    @Autowired
    private IReportAssistHanService reportAssistHanService;

    private double[] pressArray = {0.01, 0.1, 0.5, 1.0, 3.0, 5.0, 7.0, 10.0, 14.0, 20.0};
    private double[] tempArray = {100.0, 120.0, 140.0, 160.0,180.0, 200.0, 220.0, 240.0, 260.0, 280.0,300.0, 320.0, 340.0,360.0, 380.0, 400.0,420.0, 440.0,
            460.0, 480.0, 500.0, 520.0, 540.0, 560.0, 580.0, 600.0};

    /**
     * 查询辅助报表
     *
     * @param id 辅助报表ID
     * @return 辅助报表
     */
    @Override
    public ReportAssist selectReportAssistById(Long id) {
        return reportAssistMapper.selectById(id);
    }

    /**
     * 查询辅助报表列表
     *
     * @param reportAssist 辅助报表
     * @return 辅助报表
     */
    @Override
    public List<ReportAssist> selectReportAssistList(ReportAssist reportAssist) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (ObjectUtil.isNotEmpty(reportAssist)) {
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getYear()), "year", reportAssist.getYear());
            queryWrapper.like(ObjectUtil.isNotEmpty(reportAssist.getProcessName()), "process_name", reportAssist.getProcessName());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getItemRemark()), "item_remark", reportAssist.getItemRemark());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getInfoItem()), "info_item", reportAssist.getInfoItem());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getUnit()), "unit", reportAssist.getUnit());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth1()), "month1", reportAssist.getMonth1());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth2()), "month2", reportAssist.getMonth2());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth3()), "month3", reportAssist.getMonth3());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth4()), "month4", reportAssist.getMonth4());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth5()), "month5", reportAssist.getMonth5());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth6()), "month6", reportAssist.getMonth6());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth7()), "month7", reportAssist.getMonth7());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth8()), "month8", reportAssist.getMonth8());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth9()), "month9", reportAssist.getMonth9());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth10()), "month10", reportAssist.getMonth10());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth11()), "month11", reportAssist.getMonth11());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMonth12()), "month12", reportAssist.getMonth12());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getYearValue()), "year_value", reportAssist.getYearValue());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getGetWay()), "get_way", reportAssist.getGetWay());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getSource()), "source", reportAssist.getSource());
            queryWrapper.eq(ObjectUtil.isNotEmpty(reportAssist.getMaterial()), "material", reportAssist.getMaterial());
        }
        return reportAssistMapper.selectList(queryWrapper);
    }

    /**
     * 新增辅助报表
     *
     * @param reportAssist 辅助报表
     * @return 结果
     */
    @Override
    public int insertReportAssist(ReportAssist reportAssist) {
        return reportAssistMapper.insert(reportAssist);
    }

    /**
     * 修改辅助报表
     *
     * @param reportAssist 辅助报表
     * @return 结果
     */
    @Override
    public int updateReportAssist(ReportAssist reportAssist) {
        int result =  reportAssistMapper.updateById(reportAssist);
        generateAssistData(false);
        return result;
    }

    /**
     * 修改辅助报表
     *
     * @param reportAssistList 辅助报表
     * @return 结果
     */
    @Override
    public int updateReportAssistList(List<ReportAssist> reportAssistList) {
        //对输入得数据进行处理
        //各参数按四舍五入保留小数位如下 ：
        //c）电量单位为 MW∙h，保留到小数点后三位；
        //d）热量单位为 GJ，保留到小数点后两位；
        int result  = 0;
        for(int i=0;i<reportAssistList.size();i++){
            ReportAssist reportAssist = reportAssistList.get(i);
            result =  reportAssistMapper.updateById(reportAssist);
        }

        generateAssistData(false);
        return result;
    }
    private Double fixedDigitalNumber(Double number, int pointNum){
        if( number!= null){
            if(pointNum == 3){
                return Math.round(number * 1000.0) / 1000.0;
            }else if(pointNum == 2){
                return Math.round(number * 100.0) / 100.0;
            }
            return number;
        }else{
            return number;
        }
    }
    /**
     * 删除辅助报表
     *
     * @param id 辅助报表ID
     * @return 结果
     */
    @Override
    public int deleteReportAssistById(Long id) {
        return reportAssistMapper.deleteById(id);
    }

    /**
     * 批量删除辅助报表
     *
     * @param ids 辅助报表ID
     * @return 结果
     */
    @Override
    public int deleteReportAssistByIds(Long[] ids) {
        if (ids.length == 0) return 0;
        return reportAssistMapper.deleteBatchIds(ListUtil.toList(ids));
    }
    //查询已导出的文件列表
    @Override
    public List<FilenameDTO> getExportHisDataList() {
        List<FilenameDTO> filenameDTOList = new LinkedList<>();
        String dir = "furnaceExport";
        // 路径
        String path = ProjectConfig.getUploadPath();// + "/" + dir;
        File file = new File(path);
        if (!file.exists()) {
            return filenameDTOList;
        }
        //删掉三天前的文件
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, -3);
        Date newDate = calendar.getTime();
        String dateStr = sdf.format(newDate);
        List<String> fileNames = new ArrayList<>();
        List<String> files = getFileNames(file, fileNames);
        for (int i = 0; i < files.size(); i++) {
            FilenameDTO filenameDTO = new FilenameDTO();
            filenameDTO.setFileName(files.get(i));
            String genTime = files.get(i).substring(files.get(i).length()-19,files.get(i).length()-5);
//            if(genTime.compareTo(dateStr)<0){
//                String[] names = new String[1];
//                names[0] = files.get(i);
//                delExportHisData(names);
//            }else{
//                filenameDTO.setGenTime(genTime);
//                filenameDTOList.add(filenameDTO);
//            }
            //暂时不做删除三天前得操做
            filenameDTO.setGenTime(genTime);
            filenameDTOList.add(filenameDTO);
        }
        return filenameDTOList.stream()
                .sorted(Comparator.comparing(FilenameDTO::getGenTime).reversed())
                .collect(Collectors.toList());
    }
    /**
     * 得到文件名称
     *
     * @param file      文件
     * @param fileNames 文件名
     * @return {@link List}<{@link String}>
     */
    private List<String> getFileNames(File file, List<String> fileNames) {
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                getFileNames(f, fileNames);
            } else {
                fileNames.add(f.getName());
            }
        }
        return fileNames;
    }
    //删除已导出的文件列表
    @Override
    public int delExportHisData(String[] names){
        int res = 0;
        for (int i = 0; i < names.length;i++){
            String dir = "furnaceExport";
            // 路径
            String path = ProjectConfig.getUploadPath() + "/" + names[i];// + "/" + dir + "/" + names[i];
            File file = new File(path);
            if (file.exists()) {
                if(file.delete()){
                    res += 1;
                    log.info("删除文件成功："+ path);
                }else{
                    log.info("删除文件失败："+ path);
                }
            }
        }
        return res;
    }

    @Override
    public void generateAssistData(boolean isTask){
        LocalDate curDate = LocalDate.now(); // 当前日期
        Date endDate = new Date();
        // 获取本月的第一天
        LocalDate firstDayOfMonth = curDate.withDayOfMonth(1);
        // 获取当前月份的第二天的日期（不考虑年份和月份，只考虑日）
        LocalDate secondDayOfMonth = curDate.withDayOfMonth(2);
        int year = curDate.getYear();
        int month = curDate.getMonthValue();
        int day = curDate.getDayOfMonth();
        ReportAssist condition = new ReportAssist();
        condition.setYear(Convert.toStr(year));
        List<ReportAssist> dataList = selectReportAssistList(condition);
        boolean isUpdate = true;
        if(null == dataList || dataList.size() == 0){
            //新增
            isUpdate = false;
            int oldYear = year-1;
            condition.setYear(Convert.toStr(oldYear));
            dataList = selectReportAssistList(condition);
            //将默认数据全部置空重新记算
            if(null != dataList && dataList.size() != 0){
                for(int i = 0;i<dataList.size();i++)
                {
                    dataList.get(i).setId(null);
                    dataList.get(i).setYear(Convert.toStr(oldYear));
                    dataList.get(i).setMonth1(null);
                    dataList.get(i).setMonth2(null);
                    dataList.get(i).setMonth3(null);
                    dataList.get(i).setMonth4(null);
                    dataList.get(i).setMonth5(null);
                    dataList.get(i).setMonth6(null);
                    dataList.get(i).setMonth7(null);
                    dataList.get(i).setMonth8(null);
                    dataList.get(i).setMonth9(null);
                    dataList.get(i).setMonth10(null);
                    dataList.get(i).setMonth11(null);
                    dataList.get(i).setMonth12(null);
                    dataList.get(i).setYearValue(null);
                }
            }

        }
//设置值
        ReportAssist dian = dataList.stream().filter(item->item.getItemRemark().equals("dian")).collect(Collectors.toList()).get(0);
        ReportAssist gas = dataList.stream().filter(item->item.getItemRemark().equals ("gas")).collect(Collectors.toList()).get(0);
        ReportAssist temp = dataList.stream().filter(item->item.getItemRemark().equals("temp")).collect(Collectors.toList()).get(0);
        ReportAssist press = dataList.stream().filter(item->item.getItemRemark().equals("press")).collect(Collectors.toList()).get(0);

        ReportAssist han = dataList.stream().filter(item->item.getItemRemark().equals("han")).collect(Collectors.toList()).get(0);
        ReportAssist energy = dataList.stream().filter(item->item.getItemRemark().equals("energy")).collect(Collectors.toList()).get(0);
        try{
            for(int i = 1; i<= month;i++){
                //第一种化石燃料
                //先设置默认值
                Method getter = ReportAssist.class.getMethod("getMonth"+i);
                Object dianData = getter.invoke(dian); // 调用getter方法 测量值不让修改
                Object gasData = getter.invoke(gas); //
                Object tempData = getter.invoke(temp); //
                Object pressData = getter.invoke(press); //
                Method setter = ReportAssist.class.getMethod("setMonth"+i, Double.class);
                if( i == month && isTask && day != 1){//如果有点位则从点位获取

                }
                Double tempEx = findClosestValue(tempArray, Convert.toDouble(tempData, 0.0));
                Double pressEx = findClosestValue(pressArray, Convert.toDouble(pressData, 0.0));
                ReportAssistHan reportAssistHan = new ReportAssistHan();
                reportAssistHan.setTemp(tempEx);
                reportAssistHan.setPressure(pressEx);
                Double hanValue = 0.0;
                List<ReportAssistHan> hanList = reportAssistHanService.selectReportAssistHanList(reportAssistHan);
                if(null != hanList && hanList.size() != 0){
                    hanValue = hanList.get(0).getHan();

                }
                setter.invoke(han, hanValue);
                Double energyValue = Convert.toDouble(gasData, 0.0)*(hanValue-83.74)*0.001;
                setter.invoke(energy, -energyValue);
//全年设置
                if(i == 1){//设置全年
                    dian.setYearValue(Convert.toDouble(getter.invoke(dian), 0.0));
                    gas.setYearValue(Convert.toDouble(getter.invoke(gas), 0.0));
                    temp.setYearValue(Convert.toDouble(getter.invoke(temp), 0.0));
                    press.setYearValue(Convert.toDouble(getter.invoke(press), 0.0));

                    han.setYearValue(Convert.toDouble(getter.invoke(han), 0.0));
                    energy.setYearValue(Convert.toDouble(getter.invoke(energy), 0.0));


                } else if(i > 1){//设置全年
                    dian.setYearValue(dian.getYearValue() + Convert.toDouble(getter.invoke(dian), 0.0));
                    gas.setYearValue(gas.getYearValue() + Convert.toDouble(getter.invoke(gas), 0.0));
                    temp.setYearValue(temp.getYearValue() + Convert.toDouble(getter.invoke(temp), 0.0));
                    press.setYearValue(press.getYearValue() + Convert.toDouble(getter.invoke(press), 0.0));

                    han.setYearValue(han.getYearValue() + Convert.toDouble(getter.invoke(han), 0.0));
                    energy.setYearValue(energy.getYearValue() + Convert.toDouble(getter.invoke(energy), 0.0));
                }

            }
            //存储
            for(int j = 0; j<dataList.size();j++)
            {
                ReportAssist reportAssist = dataList.get(j);
                //对输入得数据进行处理
                //各参数按四舍五入保留小数位如下 ：
                //c）电量单位为 MW∙h，保留到小数点后三位；
                //d）热量单位为 GJ，保留到小数点后两位；
                int pointNum = 0;
                if(reportAssist.getInfoItem().equals("消耗电量")){
                    pointNum = 3;
                }else if(reportAssist.getInfoItem().equals("消耗热量")){
                    pointNum = 2;
                }
                if(pointNum != 0){
                    reportAssist.setMonth1(fixedDigitalNumber(reportAssist.getMonth1(), pointNum));
                    reportAssist.setMonth2(fixedDigitalNumber(reportAssist.getMonth2(), pointNum));
                    reportAssist.setMonth3(fixedDigitalNumber(reportAssist.getMonth3(), pointNum));
                    reportAssist.setMonth4(fixedDigitalNumber(reportAssist.getMonth4(), pointNum));
                    reportAssist.setMonth5(fixedDigitalNumber(reportAssist.getMonth5(), pointNum));
                    reportAssist.setMonth6(fixedDigitalNumber(reportAssist.getMonth6(), pointNum));
                    reportAssist.setMonth7(fixedDigitalNumber(reportAssist.getMonth7(), pointNum));
                    reportAssist.setMonth8(fixedDigitalNumber(reportAssist.getMonth8(), pointNum));
                    reportAssist.setMonth9(fixedDigitalNumber(reportAssist.getMonth9(), pointNum));
                    reportAssist.setMonth10(fixedDigitalNumber(reportAssist.getMonth10(), pointNum));
                    reportAssist.setMonth11(fixedDigitalNumber(reportAssist.getMonth11(), pointNum));
                    reportAssist.setMonth12(fixedDigitalNumber(reportAssist.getMonth12(), pointNum));
                }

                if(isUpdate){
                    reportAssistMapper.updateById(reportAssist);
                }else{
                    reportAssistMapper.insert(reportAssist);
                }

            }
        }catch (Exception ex){
            log.error("ex is "+ex.getMessage());
        }




    }

    public static double findClosestValue(double[] array, double target) {
        if (array == null || array.length == 0) {
            throw new IllegalArgumentException("Array must not be null or empty");
        }
        if(target == 0.0){
            return 0.0;
        }

        double closest = array[0]; // 假设第一个元素是最接近的
        for (double value : array) {
            if (Math.abs(value - target) < Math.abs(closest - target)) {
                closest = value; // 更新最接近的元素
            }
        }
        return closest;
    }
}
